#include<bits/stdc++.h>
using namespace std;
int n,m,L;
int v;
struct  car{
    int d,v,a;
}cars[100010];
struct rg{
    int idx;
    int l,r;
    bool tag;
    bool operator<(const rg t)const{
        if(r!=t.r) return r<t.r;
        return l<t.l;
    }
}rgs[100010];
int p[100010];
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d %d %d",&n,&m,&L,&v);
        memset(cars,0,sizeof cars);
        memset(rgs,0,sizeof rgs);
        memset(p,0,sizeof p);
        for(int i=0;i<n;i++) scanf("%d %d %d",&cars[i].d,&cars[i].v,&cars[i].a);
        for(int i=0;i<m;i++) scanf("%d",&p[i]);
        sort(p,p+m);
        int pos=0;
        for(int i=0;i<n;i++){
            int l,r;
            int v0=cars[i].v,a=cars[i].a,d=cars[i].d;
            if(v0>v){
                rgs[pos].l=d;
                if(a>=0) rgs[pos].r=L;
                else{
                    int xi;
                    if( (v*v-v0*v0)%(2*a)==0 ) xi=(v*v-v0*v0)/(2*a)-1;
                    else{
                        double v0f=v0,af=a;
                        double x=((double)(v*v)-v0f*v0f)/(2.0*af);
                        xi=(int)x;
                    }
                    r=d+xi;
                    if(r>L) r=L;
                    rgs[pos].r=r;
                }
                rgs[pos].idx=i;
                pos++;
            }
            else{
                if(a<=0) continue;
                else{
                    int xi;
                    if( (v*v-v0*v0)%(2*a)==0 ) xi=(v*v-v0*v0)/(2*a)+1;
                    else{
                        double v0f=v0,af=a;
                        double x=((double)(v*v)-v0f*v0f)/(2*af);
                        xi=ceil(x);
                    }
                    l=d+xi;
                    if(l>L) continue;
                    rgs[pos].l=l,rgs[pos].r=L;
                    rgs[pos].idx=i;
                    pos++;
                }
            }
        }
        int ans1=0;
        for(int i=0;i<pos;i++){
            int lb1=lower_bound(p,p+m,rgs[i].l)-p;
            int lb2=lower_bound(p,p+m,rgs[i].r)-p;
            //printf("idx=%d l=%d r=%d lb1=%d lb2=%d\n",rgs[i].idx,rgs[i].l,rgs[i].r,lb1,lb2);
            if(lb1==lb2){
                if(rgs[i].l!=p[lb1]&&rgs[i].r!=p[lb2]){
                    rgs[i].tag=1;
                    continue;
                }
            }
            ans1++;
        }
        //
        /*
        int ans1=0,pos;
        scanf("%d %d",&pos,&m);
        for(int i=0;i<pos;i++){
            scanf("%d %d",&rgs[i].l,&rgs[i].r);
        }
        for(int i=0;i<m;i++){
            scanf("%d",&p[i]);
        }*/
        sort(rgs,rgs+pos);
/*
        for(int i=0;i<pos;i++){
            printf("%d %d\n",rgs[i].l,rgs[i].r);
        }
        for(int i=0;i<m;i++){
            printf("%d\n",p[i]);
        }*/
        int ip=0,irg=0;
        int lastChoice=-1;
        set<int> ans;
        int ans2=0;
        while(1){
            while(irg<pos&&rgs[irg].tag) irg++;
            while(irg<pos&&rgs[irg].l<=lastChoice) irg++;
            if(irg>pos-1) break;
            while(ip<m&&p[ip]<=rgs[irg].r) lastChoice=p[ip],ip++;
            //printf("%d\n",lastChoice);
            ans.insert(lastChoice);
        }
        ans2=m-ans.size();
        printf("%d %d\n",ans1,ans2);
    }
    return 0;
}
